package com.tz.example.single;

import java.lang.reflect.Constructor;

/**
 * 饿汉式单例
 * 特点：
 * 1.线程安全（jvm在加类该类时，对象就new出来了，因此根本不存在线程安全问题）；
 * 2.可以通过反射破解，创建新的对象；
 * 3.因为jvm加载该类时，对象就创建了，并不是首次调用获取对象的方法时才去创建，因此不是延迟加载。
 * 4.获取和创建过程都没同步锁，不存在多线程下的同步开销问题
 * @author zhangyuetao
 */
public class HungrySingle {
    private String from;

    public String getFrom() {
        return from;
    }

    private HungrySingle(String from) {
        this.from = from;
        System.out.println("--create--from:" + from);
    }

    private static final HungrySingle single = new HungrySingle("类加载时new");

    public static HungrySingle getInstance() {
        System.out.println("--getInstance--");
        return single;
    }

    public static void main(String[] args) throws Exception {
        //多线程跑
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    HungrySingle instance = HungrySingle.getInstance();
                    System.out.println(instance.toString() + "---from:" + instance.getFrom());
                }
            }.start();
        }
        //反射创建
        Constructor<HungrySingle> declaredConstructor = HungrySingle.class.getDeclaredConstructor(String.class);
        declaredConstructor.setAccessible(Boolean.TRUE);
        HungrySingle instance2 = declaredConstructor.newInstance("反射");
        //打印hasCode
        System.out.println(instance2.toString() + "--from:" + instance2.getFrom());

    }
}
